package service

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/vueadmin/app/admin/dto"
	"github.com/vueadmin/app/admin/model"
	"github.com/vueadmin/app/admin/vo"
	"github.com/vueadmin/global"
	"github.com/vueadmin/utils/conv"
)

var AdminNodeService = new(adminNode)

type adminNode struct{}

/**
 * @description(数据列表)
 * @buildcode(true)
 */
func (p adminNode) GetPageList(req *dto.AdminNodePageReq) ([]*vo.AdminNodeList, int64, error) {
	var (
		entity model.AdminNode
		list   []*vo.AdminNodeList
		count  int64
	)
	query := global.DB.Model(&entity)
	if !conv.IsEmpty(req.NodeId) {
		query = query.Where("node_id = ?", req.NodeId)
	}
	order := "sortid asc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(order).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	query.Count(&count)

	return p.getTreeList(list, 0), count, nil
}

/**
 * @description(格式化成树形结构列表)
 * @buildcode(true)
 */
func (p adminNode) getTreeList(list []*vo.AdminNodeList, pid int) []*vo.AdminNodeList {
	res := make([]*vo.AdminNodeList, 0)
	for _, v := range list {
		if v.Pid == pid {
			v.Children = p.getTreeList(list, conv.Int(v.NodeId))
			res = append(res, v)
		}
	}
	return res
}

/**
 * @description(修改排序开关)
 * @buildcode(true)
 */
func (p adminNode) UpdateExt(req map[string]interface{}) error {
	entity := model.AdminNode{}
	if err := global.DB.Model(&entity).Where("node_id", req["node_id"]).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
 */
func (p adminNode) Add(req *dto.AdminNodeAddReq) (uint, error) {
	entity := model.AdminNode{}
	entity.Pid = req.Pid
	entity.Title = req.Title
	entity.Type = req.Type
	entity.ComponentPath = req.ComponentPath
	entity.Status = req.Status
	entity.Icon = req.Icon
	entity.Sortid = req.Sortid
	entity.Path = req.Path

	if err := global.DB.Create(&entity).Error; err != nil {
		return 0, err
	}
	if entity.Sortid == 0 {
		if err := global.DB.Model(&entity).Update("sortid", entity.NodeId).Error; err != nil {
			return 0, err
		}
	}
	return entity.NodeId, nil
}

/**
 * @description(修改)
 * @buildcode(true)
 */
func (p adminNode) Update(req *dto.AdminNodeUpdateReq) error {
	entity := model.AdminNode{
		NodeId: req.NodeId,
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.Pid = req.Pid
	entity.Title = req.Title
	entity.Type = req.Type
	entity.ComponentPath = req.ComponentPath
	entity.Status = req.Status
	entity.Icon = req.Icon
	entity.Sortid = req.Sortid
	entity.Path = req.Path

	field := conv.StringToSlice("pid,title,type,component_path,status,icon,sortid,path", ",")

	if err := global.DB.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
 */
func (p adminNode) GetUpdateInfo(req *dto.AdminNodeGetUpdateInfoReq) (*model.AdminNode, error) {
	entity := model.AdminNode{}
	if err := global.DB.Where("node_id = ?", req.NodeId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(true)
 */
func (p adminNode) Delete(req *dto.AdminNodeDeleteReq) error {
	query := global.DB.Where("node_id IN ?", conv.Slice(req.NodeId))
	if err := query.Delete(&model.AdminNode{}).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
 */
func (p adminNode) Detail(req *dto.AdminNodeDetailReq) (*vo.AdminNodeDetail, error) {
	var info vo.AdminNodeDetail
	query := global.DB.Model(&model.AdminNode{})
	if err := query.Where("node_id = ?", req.NodeId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}

/**
 * @description(查询sql下拉字段列表)
 * @buildcode(true)
 */
func (p adminNode) GetFieldList(c *gin.Context) (map[string]interface{}, error) {
	var (
		Pid []*vo.AdminNodePid
	)
	if err := global.DB.Raw(`select node_id,title,pid from cd_node`).Scan(&Pid).Error; err != nil {
		return nil, err
	}
	data := make(map[string]interface{})
	data["pids"] = p.getTreePid(Pid, 0)
	return data, nil
}

/**
 * @description(格式所属父类树形结构)
 * @buildcode(true)
 */
func (p adminNode) getTreePid(list []*vo.AdminNodePid, pid int) []*vo.AdminNodePid {
	res := make([]*vo.AdminNodePid, 0)
	for _, v := range list {
		if v.Pid == pid {
			v.Children = p.getTreePid(list, v.NodeId)
			res = append(res, v)
		}
	}
	return res
}
